/******************************************************************************
 * @File name   :      AuthInterceptor.java
 *
 * @Author      :      junyi cai
 *
 * @Date        :      2011-4-8
 *
 * @Copyright Notice: 
 * Copyright (c) 2014 DMS, Inc. All  Rights Reserved.
 * This software is published under the terms of the DMS Software
 * License version 1.0, a copy of which has been included with this
 * distribution in the LICENSE.txt file.
 * 
 * 
 * ----------------------------------------------------------------------------
 * Date                   Who         Version        Comments
 * 2011-4-8 ä¸‹å�ˆ05:02:34        junyi cai     1.0            Initial Version
 * 2011-9-29 ä¸‹å�ˆ04:27:03       Wu Jianxi     1.1            add static resource filter & add token validation
 * 2011-12-1 ä¸‹å�ˆ04:38:41           caijunyi            1.1              fix export bug
 *****************************************************************************/
package com.cap.bts.framework.auth.filter;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.cap.bts.crmdp.dealer.mars.constants.MARSConstants;
import com.cap.bts.framework.auth.constant.AuthConstant;
import com.cap.bts.framework.auth.util.PropertiesUtil;
import com.cap.bts.framework.auth.util.SSOConfigurations;
import com.cap.bts.framework.auth.util.UserAuthenticationUtils;
import com.cap.bts.framework.auth.util.WebUtils;
import com.cap.bts.framework.common.constant.CommonErrorConstants;
import com.cap.bts.framework.common.exception.AppException;
import com.cap.bts.framework.common.util.ApplicationContextUtil;
import com.cap.bts.framework.common.util.CookieUtils;
import com.cap.bts.framework.common.util.Utils;
import com.cap.bts.framework.menu.domain.Menu;
import com.cap.bts.framework.menu.service.IMenuService;
import com.cap.bts.framework.usermgnt.domain.User;

/**
 *
 */
public class AuthInterceptor extends HandlerInterceptorAdapter {
    
    private static Logger logger = Logger.getLogger(AuthInterceptor.class);
    
    
    private static IMenuService menuService;
    
    @Override
    public boolean preHandle(HttpServletRequest req,
            HttpServletResponse res, Object handler) throws Exception {
    	String a = req.getRequestURI();
        if(req.getRequestURI().endsWith(".js") || req.getRequestURI().endsWith(".css")
            || req.getRequestURI().endsWith(".jpg") || req.getRequestURI().endsWith(".gif")
            || req.getRequestURI().endsWith(".mp3") || req.getRequestURI().endsWith(".png")
            || req.getRequestURI().endsWith(".bmp") || req.getRequestURI().endsWith(".htm")
            || MARSConstants.checkMARSUrl(req.getRequestURI())
            || req.getRequestURI().endsWith("/login/toSelectedOrgs")//加入多门店选择页面过滤 modify by Zach
        		){
            return true;
        }

        User user = (User) RequestContextHolder.currentRequestAttributes().getAttribute("userSession", RequestAttributes.SCOPE_SESSION);
        
//        // set the properties values
        UserAuthenticationUtils.initProValue();
//        //First request to login
        String loginUrlSuffix =  AuthConstant.LOGIN_PAGE_URL;
        String monitorLoginUrlSuffix = AuthConstant.MONITOR_LOGIN_PAGE_URL;
//        // "/monitorLogin";
        
        logger.debug("login url " + req.getContextPath() + loginUrlSuffix) ;
        if (req.getRequestURI().equals(req.getContextPath() + loginUrlSuffix)
                || req.getRequestURI().equals(req.getContextPath() + monitorLoginUrlSuffix)
                || req.getRequestURI().equals(req.getContextPath() + "/ge/dealer/resetpasswd/toResetPwd")){
        	String isForceLogout = CookieUtils.getCookie(req, res, AuthConstant.COOKIE_IS_FORCE_LOGOUT);
            if(Utils.notEmpty(isForceLogout) && isForceLogout.equals("true")){
            	/**
                 * Set the flag of force invalid session because of multiple client login
                 */
                req.getSession().setAttribute("isForceLogout", true);
            }
        	return true;
        } else if(UserAuthenticationUtils.isResetPasswordRequest(req)){
            return true;
        } else if (req.getRequestURI().equals(req.getContextPath() + AuthConstant.RESET_FORCE_LOGOUT)){
        	return true;
        } else if (/*UserAuthenticationUtils.isTrustedUser(req, res) &&*/ user != null) {
            // has logined and session has not expired
            logger.debug("login yet, set the user info to cookie");
            UserAuthenticationUtils.setLoginToCookie(req, res,
                    UserAuthenticationUtils.getLoginUserId(req, res));
            String requestMethod=req.getMethod();
            String uri=req.getRequestURI().toLowerCase();
            String subUri=uri.substring(uri.lastIndexOf("/"),uri.length());
            if(requestMethod!=null && requestMethod.equalsIgnoreCase("POST")){// only 'post' method need check duplicate submit            	
            	if(subUri.contains("list")
            			|| subUri.contains("get")
            			|| subUri.contains("find")
            			|| subUri.contains("valid")
            			|| subUri.contains("search")
            			|| subUri.contains("verify")
            			|| subUri.contains("back")
            			|| subUri.contains("check")
            			|| subUri.contains("view")
            			|| subUri.contains("/to")
            			){// do not need check duplicate submit if uri contains 'query','get','find','list','valid','search','verify'
            		
            	}else{
            		if(!processToken(req)){
            			//                return false;
            			throw new AppException (CommonErrorConstants.COMMON_DUPLICATED_FORM_SUBMIT,"duplicated submit ");
            		}
            		
            	}
            }	
            
            //set can export data to cookie
//            UserAuthenticationUtils.setCookie(req, res,
//            UserAuthenticationUtils.getCanExportValue(req, res));
            
//            String userCode = CookieUtils.getCookie(req, res, "user");
//            String tokenStr = req.getParameter(CommonConstants.SESSION_KEY_TOKEN);
            
//            return processToken(tokenStr, userCode);
            String flag = (String) RequestContextHolder.currentRequestAttributes().getAttribute("operationPwdFlag", RequestAttributes.SCOPE_SESSION);
            if("1".equals(flag)){
                return true;
            }else{
                String url = req.getRequestURI();
                String subUrl = url.substring(5);//  remove "/crm"
                
               //处理/crm情况 modify by Zach:20151012
                if("".equals(subUrl)){
                	//WebUtils.redirectAccess(req, res, req.getContextPath(), "buildMenu",null);
                	res.sendRedirect("buildMenu");
                	return false;
				}
                
                IMenuService menuService = (IMenuService)ApplicationContextUtil.getApplicationContext().getBean("menuService");
                List<Menu> menuList = menuService.getMenuByUrl(subUrl);
                if(menuList != null && !menuList.isEmpty()){
                    Menu menu = menuList.get(0);
                    if((menu.getIsPwdRequired())==1){
                        req.getSession().setAttribute("url", subUrl);
                        req.getSession().setAttribute("dealerNum", user.getUserCode());
                        String uriString = "login/toPwdRequired";
                        //WebUtils.redirectAccess(req, res, req.getContextPath(), uriString,null);
                        res.sendRedirect(uriString);
                    }else{
                        return true;
                    }
                }
            }
            
            return true;
        } else {
            logger.debug("not yet login,redirect to login page");
//            String dmsLoginUrl = PropertiesUtil.getProperties(AuthConstant.DMS_LOGIN_URL_KEY);
            /**
             * Set the flag of force invalid session because of multiple client login
             */
            req.getSession().setAttribute("isForceLogout", UserAuthenticationUtils.isForceLogout(req,res));
            
//            WebUtils.redirectToLoginByFullUrl(req, res, dmsLoginUrl);
            String url = SSOConfigurations.getConfig("dealer.portal.url");
    		res.sendRedirect(url);
            return false;
        } 
    }
    
    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      2011-12-21
     * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#postHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.web.servlet.ModelAndView)
    **/
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
        Object handler, ModelAndView modelAndView) throws Exception {
        /*if(request.getRequestURI().endsWith(".js") || request.getRequestURI().endsWith(".css")
            || request.getRequestURI().endsWith(".jpg") || request.getRequestURI().endsWith(".gif")
            || request.getRequestURI().endsWith(".bmp")){
            super.postHandle(request, response, handler, modelAndView);
        }else{
            String sessionTokenKey=request.getRequestURI();
            HttpSession session =request.getSession();
            if(session!=null){
                Object tokenObj=session.getAttribute("tokenMap");
                if(tokenObj!=null){
                    Map<String,String> tokenMap=(Map<String,String>)tokenObj;
                    tokenMap.remove(sessionTokenKey);
    //                session.removeAttribute(sessionTokenKey);
                }
    //            session.removeAttribute("tokenMap");   
            }
            super.postHandle(request, response, handler, modelAndView);
        }*/
        super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      2011-12-21
     * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterCompletion(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
    **/
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
        Object handler, Exception ex) throws Exception {

        if(request.getRequestURI().endsWith(".js") || request.getRequestURI().endsWith(".css")
            || request.getRequestURI().endsWith(".jpg") || request.getRequestURI().endsWith(".gif")
            || request.getRequestURI().endsWith(".bmp")){
            super.afterCompletion(request, response, handler, ex);
        }else{
            String sessionTokenKey=request.getRequestURI();
            HttpSession session =request.getSession(false);
            if(session!=null){
                Object tokenObj=session.getAttribute("tokenMap");
                if(tokenObj!=null){
                    Map<String,String> tokenMap=(Map<String,String>)tokenObj;
                    tokenMap.remove(sessionTokenKey);
    //                session.removeAttribute(sessionTokenKey);
                }
    //            session.removeAttribute("tokenMap");   
            }
            super.afterCompletion(request, response, handler, ex);
        }
    }

    private boolean processToken(HttpServletRequest request){
//        String sessionTokenKey = CachePrefix.SESSION_TOKEN + CachePrefix.DIVIDE + userCode;
        String sessionTokenKey=request.getRequestURI();
        HttpSession session =request.getSession();
//        session.removeAttribute("tokenMap");  
        if(session!=null){
            Map<String,String> tokenMap=new HashMap<String,String>();
            Object tokenObj=session.getAttribute("tokenMap");
            if(tokenObj!=null){
                tokenMap=(Map<String,String>)tokenObj;
                String token=tokenMap.get(sessionTokenKey);
                if(token!=null){
                    return false;
                }else{
                    tokenMap.put(sessionTokenKey, String.valueOf(System.currentTimeMillis()));
                    session.setAttribute("tokenMap", tokenMap);
                }
            }else{
                tokenMap.put(sessionTokenKey, String.valueOf(System.currentTimeMillis()));
                session.setAttribute("tokenMap", tokenMap);
            }
//            Object token=session.getAttribute(sessionTokenKey);
//            if(token!=null){
//                return false;
//            }else{
//                session.setAttribute(sessionTokenKey, System.currentTimeMillis());
//                return true;
//            }
        }
        return true;
        
               
//        //å¦‚æžœæ²¡æœ‰æ��äº¤tokenï¼Œåˆ™åœ¨cacheä¸­åˆ é™¤è¯¥Tokenã€‚
//        if(tokenStr == null ){
//            if(CacheUtil.containsCache(sessionTokenKey)){
//                CacheUtil.removeCache(sessionTokenKey);
//            }
//            return true;
//        }
//        //å¦‚æžœformä¸­æ��äº¤çš„tokenå’ŒCacheä¸­ä¸€è‡´çš„è¯�,åˆ™ç§»é™¤Cacheä¸­çš„token
//        if(tokenStr.equals((String)CacheUtil.getCache(sessionTokenKey))){
//            CacheUtil.removeCache(sessionTokenKey);
//            return true;
//        }else{
//            //å�¦åˆ™ï¼Œç›´æŽ¥è·³è¿‡Controller
//            return false;
//        }
    }
}
